package com.li.springbootproject.spring.beaninit;

import com.li.springbootproject.domain.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

/**
 * @author LiDong
 * @version 1.0.0
 * @className BeanTest.java
 * @createTime 2021年06月14日 21:42:00
 */
@Component
public class BeanTest implements BeanNameAware, ApplicationContextAware, BeanPostProcessor, InitializingBean {

    private static final Logger logger = LoggerFactory.getLogger(BeanTest.class);

    /**
     * Spring Bean 的生命周期
     * <p>
     * 实例化 ——》 填充属性 ——》
     * ——》 调用 BeanNameAware 的 setBeanName()
     * ——》 调用 BeanFactory 的 setBeanFactory()
     * ——》 调用 ApplicationContextAware 的setApplication()
     * ——》 调用 Bean 前置处理器 BeanPost-Processor 的预初始初化方法
     * ——》 调用 InitialLizingBean 的 set()
     * ——》 调用自定义的初始化方法
     * ——》 调用 Bean 后置处理器 BeanPost-Processor
     * ——》 Bean 可以使用
     * ——》 调用 Destory() 销毁 Bean
     */


    @Bean(name = "testUser")
    public User testUserBean() {
        User user = new User();
        return user;
    }


    /**
     * 设置Bean 名称
     *
     * @param s
     */
    @Override
    public void setBeanName(String s) {
        logger.info(s);
    }

    /**
     * 设置上下文容器
     *
     * @param applicationContext
     * @throws BeansException
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        logger.info(String.valueOf(applicationContext));
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
    }


    @Override
    public void afterPropertiesSet() throws Exception {
        logger.info("TestUserBean Init afterPropertiesSet()...");
    }


    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }


}
